using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;


namespace Parsifal
{
    public class protocolParserClient
    {

        Utility iUtility;


        public event OnWelcomeNick _OnWelcomeNick;

        public event OnPlaylistItem _OnPlaylistItem;

        public event OnPlaylistItemAdd _OnPlaylistItemAdd;

        public event OnPlaylistItemRemove _OnPlaylistItemRemove;

        public event OnPlaylistItemLast _OnPlaylistItemLast;

        public event OnSongActive _OnSongActive;

        public event OnMessaggeReceived _OnMessageReceived;

        public event OnMessageSendReceived _OnMessageSendReceived;

        public event OnCreateServer _OnCreateServer;

        public event OnConnectTo _OnConnectTo;

        public event OnStopServer _OnStopServer;

        public event OnSpeackerOn _OnSpeackerOn;

        public event OnSpeackerOff _OnSpeackerOff;

        public protocolParserClient(Utility aUtility)
        {
            iUtility = aUtility;
        }
    
        public eProtocolClientEvent eProtocolClientEvent
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
        #region delegate and event

        public delegate void OnWelcomeNick(Socket remote, string msg,eProtocolClientEvent iRes);
        public delegate void OnPlaylistItem(PlaylistItem aItem, Socket remote, eProtocolClientEvent iRes);
        public delegate void OnPlaylistItemAdd(PlaylistItem aItem, Socket remote, eProtocolClientEvent iRes);
        public delegate void OnPlaylistItemRemove(PlaylistItem aItem, Socket remote, eProtocolClientEvent iRes);
        public delegate void OnPlaylistItemLast(Socket remote, eProtocolClientEvent iRes);
        public delegate void OnSongActive(PlaylistItem aItem, Socket remote, eProtocolClientEvent iRes);
        public delegate void OnMessaggeReceived(string msg, string nick, Socket remote, eProtocolClientEvent iRes);
        public delegate void OnMessageSendReceived(Socket remote, eProtocolClientEvent iRes);
        public delegate void OnCreateServer(Socket remote, eProtocolClientEvent iRes);
        public delegate void OnConnectTo(Socket remote, string addressServer, eProtocolClientEvent iRes);
        public delegate void OnStopServer(Socket remote, eProtocolClientEvent iRes);
        public delegate void OnSpeackerOn(Socket remote, eProtocolClientEvent iRes);
        public delegate void OnSpeackerOff(Socket remote, eProtocolClientEvent iRes);


        #endregion

        public void GetDataFromSocket(string data, Socket remote)
        {
            try
            {
                //find command
                int sepLength = eWordCodeForProtocol.mMainSeparator.Length;
                int pos = data.IndexOf(eWordCodeForProtocol.mMainSeparator);
                string comando = data.Substring(0, pos);

                //cancello il comando
                data = data.Remove(0, pos + sepLength);

                switch (comando)
                {
                    case eWordCodeForProtocol.mWelcomeMsg:
                        {
                            iUtility.LogEvent("PARSER CLIENT : fx Welcome Msg : ok", NLog.LogLevel.Info);
                            
                            int poss3 = data.IndexOf("##", 0);
                            string msg = data.Substring(0, poss3);


                            iUtility.LogEvent("PARSER CLIENT : fx Welcome Msg : dati " + msg, NLog.LogLevel.Info);


                            if (_OnWelcomeNick != null)
                            {
                                _OnWelcomeNick(remote, msg, eProtocolClientEvent.WELCOME_NICK);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mConnectTo:
                        {
                            

                            int posS = data.IndexOf("##", 0);
                            string addr = data.Substring(0, posS);

                            iUtility.LogEvent("PARSER CLIENT : Connect to: dati : " + addr, NLog.LogLevel.Info);

                            if (_OnConnectTo != null)
                            {
                                _OnConnectTo(remote, addr, eProtocolClientEvent.CONNECT_TO);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mCreateServer:
                        {

                            if (_OnCreateServer != null)
                            {
                                _OnCreateServer(remote, eProtocolClientEvent.CREATE_SERVER);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mMsgSend:
                        {
                            iUtility.LogEvent("PARSER CLIENT : enter MessageSend: ok", NLog.LogLevel.Info);


                            int poss = data.IndexOf("/", 0);
                            string nick = data.Substring(0, poss);
                            data = data.Remove(0, poss + 1);

                            int poss2 = data.IndexOf("##", 0);
                            string msg = data.Substring(0, poss2);
                            data = data.Remove(0, poss2 + 2);

                            iUtility.LogEvent("PARSER CLIENT : dati msg ricevuto : " + nick + " dice " + msg, NLog.LogLevel.Info);

                            if (_OnMessageReceived != null)
                            {
                                _OnMessageReceived(msg, nick, remote, eProtocolClientEvent.MSG_RECEIVED);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mMsgSendRec:
                        {
                            iUtility.LogEvent("PARSER CLIENT : enter Message Send Received: ok", NLog.LogLevel.Info);


                            iUtility.LogEvent("PARSER CLIENT : enter Message Send Received: out", NLog.LogLevel.Info);


                            if (_OnMessageSendReceived != null)
                            {
                                _OnMessageSendReceived(remote, eProtocolClientEvent.MSG_SEND_REC);
                            }
                            

                        }
                        break;
                    case eWordCodeForProtocol.mPlaylistItem:
                        {
                            //aggiunge una playlist all'elenco

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItem: ok", NLog.LogLevel.Info);
                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItem: dati entranti :  " + data, NLog.LogLevel.Info);

                            int posint = data.IndexOf("##");
                            string datiTemp = data.Substring(0, posint);

                            PlaylistItem aItem = getPlaylistInfoFromStream(data);

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItem: dati song :  " + aItem.Artist + " " + aItem.Song +
                                " " + aItem.Duration + " " + aItem.NickServer, NLog.LogLevel.Info);

                            if (_OnPlaylistItem != null)
                            {
                                _OnPlaylistItem(aItem, remote, eProtocolClientEvent.PLAYLIST_ITEM);
                            }

                        }
                        break;
                    case eWordCodeForProtocol.mPlaylistItemAdd:
                        {
                             //aggiunge una playlist all'elenco

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemAdd: ok", NLog.LogLevel.Info);
                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemAdd: dati entranti :  " + data, NLog.LogLevel.Info);

                            int posint = data.IndexOf("##");
                            string datiTemp = data.Substring(0, posint);

                            PlaylistItem aItem = getPlaylistInfoFromStream(data);

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemAdd: dati song :  " + aItem.Artist + " " + aItem.Song +
                                " " + aItem.Duration + " " + aItem.NickServer, NLog.LogLevel.Info);

                            if (_OnPlaylistItemAdd != null)
                            {
                                _OnPlaylistItemAdd(aItem, remote, eProtocolClientEvent.PLAYLIST_ITEM_ADD);
                            }

                        }
                        break;
                    case eWordCodeForProtocol.mPlaylistItemLast:
                        {
                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemLAST: ok", NLog.LogLevel.Info);

                            if (_OnPlaylistItemLast != null)
                            {
                                _OnPlaylistItemLast(remote, eProtocolClientEvent.PLAYLIST_ITEM_LAST);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mPlaylistItemRem:
                        {

                            //aggiunge una playlist all'elenco

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemRem: ok", NLog.LogLevel.Info);
                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemRem: dati entranti :  " + data, NLog.LogLevel.Info);

                            int posint = data.IndexOf("##");
                            string datiTemp = data.Substring(0, posint);

                            PlaylistItem aItem = getPlaylistInfoFromStream(data);

                            iUtility.LogEvent("PARSER CLIENT: enter mPLaylistItemRem: dati song :  " + aItem.Artist + " " + aItem.Song +
                                " " + aItem.Duration + " " + aItem.NickServer, NLog.LogLevel.Info);

                            if (_OnPlaylistItemRemove != null)
                            {
                                _OnPlaylistItemRemove(aItem, remote, eProtocolClientEvent.PLAYLIST_ITEM_REM);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mSongActive:
                        {
                            //aggiunge una playlist all'elenco

                            iUtility.LogEvent("PARSER CLIENT: enter mSongActive: ok", NLog.LogLevel.Info);
                            iUtility.LogEvent("PARSER CLIENT: enter mSongActive: dati entranti :  " + data, NLog.LogLevel.Info);

                            int posint = data.IndexOf("##");
                            string datiTemp = data.Substring(0, posint);

                            PlaylistItem aItem = getPlaylistInfoFromStream(data);

                            iUtility.LogEvent("PARSER CLIENT: enter mSongActive: dati song :  " + aItem.Artist + " " + aItem.Song +
                                " " + aItem.Duration + " " + aItem.NickServer, NLog.LogLevel.Info);

                            if (_OnSongActive != null)
                            {
                                _OnSongActive(aItem, remote, eProtocolClientEvent.SONG_ACTIVE);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mSpeackerOff:
                        {
                            iUtility.LogEvent("PARSER CLIENT: enter speacker off: ok", NLog.LogLevel.Info);

                            if (_OnSpeackerOff != null)
                            {
                                _OnSpeackerOff(remote, eProtocolClientEvent.SPEACKER_OFF);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mSpeackerOn:
                        {
                            iUtility.LogEvent("PARSER CLIENT: enter speacker on: ok", NLog.LogLevel.Info);

                            if (_OnSpeackerOn != null)
                            {
                                _OnSpeackerOn(remote, eProtocolClientEvent.SPEACKER_ON);
                            }
                        }
                        break;
                    case eWordCodeForProtocol.mStopServer:
                        {
                            iUtility.LogEvent("PARSER CLIENT: enter stop server: ok", NLog.LogLevel.Info);

                            if (_OnStopServer != null)
                            {
                                _OnStopServer(remote, eProtocolClientEvent.STOP_SERVER);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            catch (Exception err)
            {
                
                throw new Exception("errore generico al protocol parser Client");
            }
        }

        PlaylistItem getPlaylistInfoFromStream(string data)
        {
            try
            {
                PlaylistItem aItemTemp = new PlaylistItem();

                //formato   "artista/song/durata/nickserver##"

                int pos1 = data.IndexOf("/", 0);
                string artista = data.Substring(0, pos1);
                data = data.Remove(0, pos1 + 1);

                int pos2 = data.IndexOf("/", 0);
                string song = data.Substring(0, pos2);
                data = data.Remove(0, pos2 + 1);

                int pos3 = data.IndexOf("/", 0);
                string durata = data.Substring(0, pos3);
                data = data.Remove(0, pos3 + 1);

                int pos4 = data.IndexOf("##", 0);
                string nickServer = data.Substring(0, pos4);
                data = data.Remove(0, pos4 + 2);

                aItemTemp.Artist = artista;
                aItemTemp.Song = song;
                aItemTemp.Duration = durata;
                aItemTemp.NickServer = nickServer;

                return aItemTemp;
            }
            catch (Exception err)
            {

                throw new Exception("Errore nella decodifica delle informazioni della playlist. Controllare il formato");
            }
        }

        
    }


}
